/*
 * Javlov - a Java toolkit for reinforcement learning with multi-agent support.
 * 
 * Copyright (c) 2009 Matthijs Snel
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.javlov.world.grid;

import net.javlov.AbstractPrimitiveAction;
import net.javlov.Action;
import net.javlov.Agent;
import net.javlov.State;
import net.javlov.world.Body;

public class GridMove extends AbstractPrimitiveAction {

	private static final long serialVersionUID = -7313390305297377095L;
	
	public static GridMove getNorthInstance(GridWorld w) {
		return new GridMove("NORTH:1", w, Direction.north, 1);
	}
	
	public static GridMove getNorthEastInstance(GridWorld w) {
		return new GridMove("NORTHEAST:1", w, Direction.northeast, 1);
	}
	
	public static GridMove getEastInstance(GridWorld w) {
		return new GridMove("EAST:1", w, Direction.east, 1);
	}
	
	public static GridMove getSouthEastInstance(GridWorld w) {
		return new GridMove("SOUTHEAST:1", w, Direction.southeast, 1);
	}
	
	public static GridMove getSouthInstance(GridWorld w) {
		return new GridMove("SOUTH:1", w, Direction.south, 1);
	}
	
	public static GridMove getSouthWestInstance(GridWorld w) {
		return new GridMove("SOUTHWEST:1", w, Direction.southwest, 1);
	}
	
	public static GridMove getWestInstance(GridWorld w) {
		return new GridMove("WEST:1", w, Direction.west, 1);
	}
	
	public static GridMove getNorthWestInstance(GridWorld w) {
		return new GridMove("NORTHWEST:1", w, Direction.northwest, 1);
	}
	
	protected transient GridWorld world;
	protected Direction dir;
	protected int speed;
	
	public GridMove(GridWorld w, Direction dir, int speed) {
		this("GridMove [" + dir.x() + "," + dir.y() + "]:" + speed, w, dir, speed );
	}
	
	public GridMove(String name, GridWorld w, Direction dir, int speed) {
		super(name);
		this.world = w;
		this.dir = dir;
		this.speed = speed;
	}
	
	@Override
	public void execute(Agent a) {
		Body b = world.getAgentBody(a);
		world.translateBody(b, dir, speed);		
	}
	
	@Override
	public <T> Action doStep(State<T> s, double reward) {
		return this;
	}
	
	@Override
	public <T> Action firstStep(State<T> s) {
		return this;
	}
	
	public double[] getValues() {
		return new double[]{dir.x(), dir.y()};
	}
	
}
